<template>
  <div class="compose-page">
    <!-- 素材库选择模式 -->
    <div class="library-mode">
      <el-row :gutter="24">
        <!-- 数字人选择 -->
        <el-col :span="12">
          <el-card class="page-card selection-card">
            <template #header>
              <div class="card-header">
                <span><el-icon><User /></el-icon> 选择数字人</span>
                <span class="selected-count" v-if="selectedHumans.length > 0">
                  已选择 {{ selectedHumans.length }} 个
                </span>
                <el-button type="primary" @click="goToHumanLibrary">
                  前往数字人库
                </el-button>
              </div>
            </template>

            <!-- 搜索和排序 -->
            <div class="selection-controls">
              <el-input
                  v-model="humanSearchKeyword"
                  placeholder="搜索数字人名称"
                  prefix-icon="Search"
                  clearable
                  @input="searchHumans"
                  style="flex: 1;"
              />
              <el-select v-model="humanSortBy" @change="loadHumans" style="width: 150px;">
                <el-option label="最新上传" value="time_desc" />
                <el-option label="最早上传" value="time_asc" />
                <el-option label="名称排序" value="name" />
                <el-option label="大小排序" value="size" />
              </el-select>
            </div>

            <div class="selection-grid" v-loading="humanLoading">
              <div
                  v-for="human in humanList"
                  :key="human.file_id"
                  class="selection-item"
                  :class="{ selected: isHumanSelected(human.file_id) }"
                  @click="toggleHumanSelection(human)"
              >
                <el-image
                    :src="`${basePythonURL2}/api/preview-file/${human.file_id}`"
                    fit="cover"
                    class="item-preview"
                    lazy
                >
                  <template #error>
                    <div class="image-error">
                      <el-icon><VideoPlay /></el-icon>
                    </div>
                  </template>
                </el-image>
                <div class="item-info">
                  <span class="item-name" :title="human.original_name">{{ human.original_name }}</span>
                  <el-tag size="small">{{ formatFileSize(human.file_size) }}</el-tag>
                </div>
                <div v-if="isHumanSelected(human.file_id)" class="selected-badge">
                  <el-icon><Check /></el-icon>
                </div>
              </div>
            </div>

            <el-empty v-if="!humanLoading && humanList.length === 0" description="暂无数字人文件" />

            <!-- 分页 -->
            <div class="selection-pagination">
              <el-pagination
                  v-model:current-page="humanPage"
                  v-model:page-size="humanPageSize"
                  :page-sizes="[8, 16, 24, 48]"
                  :total="humanTotal"
                  layout="total, sizes, prev, pager, next"
                  small
                  @size-change="loadHumans"
                  @current-change="loadHumans"
              />
            </div>
          </el-card>
        </el-col>

        <!-- 背景选择 -->
        <el-col :span="12">
          <el-card class="page-card selection-card">
            <template #header>
              <div class="card-header">
                <span><el-icon><Picture /></el-icon> 选择背景素材</span>
                <span class="selected-count" v-if="selectedBackgrounds.length > 0">
                  已选择 {{ selectedBackgrounds.length }} 个
                </span>
                <el-button type="primary" @click="goToMaterialLibrary">
                  前往素材库
                </el-button>
              </div>
            </template>

            <!-- 筛选、搜索和排序 -->
            <div class="selection-controls">
              <el-select v-model="bgFilterType" @change="loadBackgrounds" style="width: 100px;">
                <el-option label="全部" value="all" />
                <el-option label="图片" value="image" />
                <el-option label="视频" value="video" />
                <el-option label="GIF" value="gif" />
              </el-select>
              <el-input
                  v-model="bgSearchKeyword"
                  placeholder="搜索背景名称"
                  prefix-icon="Search"
                  clearable
                  @input="searchBackgrounds"
                  style="flex: 1;"
              />
              <el-select v-model="bgSortBy" @change="loadBackgrounds" style="width: 150px;">
                <el-option label="最新上传" value="time_desc" />
                <el-option label="最早上传" value="time_asc" />
                <el-option label="名称排序" value="name" />
                <el-option label="大小排序" value="size" />
              </el-select>
            </div>

            <div class="selection-grid" v-loading="bgLoading">
              <div
                  v-for="bg in backgroundList"
                  :key="bg.file_id"
                  class="selection-item"
                  :class="{ selected: isBackgroundSelected(bg.file_id) }"
                  @click="toggleBackgroundSelection(bg)"
              >
                <el-image
                    :src="`${basePythonURL2}/api/preview-file/${bg.file_id}`"
                    fit="cover"
                    class="item-preview"
                    lazy
                >
                  <template #error>
                    <div class="image-error">
                      <el-icon><Picture /></el-icon>
                    </div>
                  </template>
                </el-image>
                <div class="item-info">
                  <span class="item-name" :title="bg.original_name">{{ bg.original_name }}</span>
                  <el-tag size="small" :type="getFileTypeTagType(bg.original_name)">
                    {{ getFileType(bg.original_name).toUpperCase() }}
                  </el-tag>
                </div>
                <div v-if="isBackgroundSelected(bg.file_id)" class="selected-badge">
                  <el-icon><Check /></el-icon>
                </div>
              </div>
            </div>

            <el-empty v-if="!bgLoading && backgroundList.length === 0" description="暂无背景素材" />

            <!-- 分页 -->
            <div class="selection-pagination">
              <el-pagination
                  v-model:current-page="bgPage"
                  v-model:page-size="bgPageSize"
                  :page-sizes="[8, 16, 24, 48]"
                  :total="bgTotal"
                  layout="total, sizes, prev, pager, next"
                  small
                  @size-change="loadBackgrounds"
                  @current-change="loadBackgrounds"
              />
            </div>
          </el-card>
        </el-col>
      </el-row>

      <!-- 生成组合按钮 -->
      <div class="generate-combinations-wrapper" v-if="canGenerateCombinations">
        <el-button
            type="primary"
            size="large"
            @click="handleGenerateCombinations"
        >
          <el-icon><Connection /></el-icon>
          生成组合 ({{ selectedHumans.length }} × {{ selectedBackgrounds.length }} = {{ selectedHumans.length * selectedBackgrounds.length }})
        </el-button>
      </div>
    </div>

    <!-- 参数设置面板 -->
    <el-card
        v-if="combinations.length > 0"
        class="page-card params-card"
    >
      <template #header>
        <div class="card-header">
          <span><el-icon><Setting /></el-icon> 全局参数设置</span>
          <div class="header-actions">
            <el-button @click="showPresetSelector = true">
              <el-icon><Collection /></el-icon>
              应用预设
            </el-button>
            <el-button type="primary" @click="applyGlobalParams">
              应用到所有组合
            </el-button>
            <el-button
                @click="paramsExpanded = !paramsExpanded"
                :icon="paramsExpanded ? 'ArrowUp' : 'ArrowDown'"
            >
              {{ paramsExpanded ? '折叠' : '展开' }}
            </el-button>
          </div>
        </div>
      </template>

      <!-- 快速预设选择 -->
      <div class="quick-presets" v-if="recentPresets.length > 0">
        <div class="preset-label">快速应用预设：</div>
        <div class="preset-buttons">
          <el-button
              v-for="preset in recentPresets"
              :key="preset.id"
              size="small"
              @click="applyGlobalPreset(preset)"
          >
            <el-icon><Collection /></el-icon>
            {{ preset.name }}
          </el-button>
          <el-button size="small" @click="showPresetSelector = true">
            更多预设...
          </el-button>
        </div>
      </div>

      <!-- 参数设置内容 -->
      <el-collapse-transition>
        <div v-show="paramsExpanded">
          <GlobalParams v-model="globalParams" :compact="false" />
        </div>
      </el-collapse-transition>
    </el-card>

    <!-- 组合列表 -->
    <el-card
        v-if="combinations.length > 0"
        class="page-card combinations-card"
    >
      <template #header>
        <div class="card-header">
          <span><el-icon><Grid /></el-icon> 组合列表 ({{ combinations.length }}个)</span>
          <div>
            <el-button @click="clearAllCombinations">清空所有</el-button>
            <el-button type="success" @click="batchProcess">
              <el-icon><VideoPlay /></el-icon>
              批量处理
            </el-button>
          </div>
        </div>
      </template>

      <el-table :data="combinations" style="width: 100%">
        <el-table-column label="预览" width="140">
          <template #default="{ row }">
            <div class="combination-preview" @click="editCombination(row)">
              <el-icon><View /></el-icon>
              <span>编辑预览</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="human.original_name" label="数字人" min-width="200" />
        <el-table-column prop="background.original_name" label="背景" min-width="200" />
        <el-table-column label="输出名称" min-width="200">
          <template #default="{ row }">
            <el-input
                v-model="row.output_name"
                size="small"
                @change="updateCombinationName(row)"
            />
          </template>
        </el-table-column>
        <el-table-column label="参数状态" width="120">
          <template #default="{ row }">
            <el-tag
                size="small"
                :type="row.isCustomParams ? 'success' : 'info'"
            >
              {{ row.isCustomParams ? '自定义' : '默认' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="160">
          <template #default="{ row }">
            <el-button type="primary" size="small" @click="processSingle(row)">
              处理
            </el-button>
            <el-button type="danger" size="small" @click="removeCombination(row)">
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 处理进度 -->
    <ProcessingProgress
        v-if="processingTasks.length > 0"
        :tasks="processingTasks"
        @complete="handleProcessComplete"
    />

    <!-- 新的组合编辑对话框 -->
    <CombinationEditDialog
        v-model="editDialogVisible"
        :combination="editingCombination"
        @update="updateCombinationParams"
        @startProcess="processSingle"
    />

    <!-- 预设选择对话框 -->
    <PresetManagerDialog
        v-model="showPresetSelector"
        @apply="applyGlobalPreset"
    />
  </div>
</template>

<script setup>
import { ref, computed, onMounted, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import {ElAlert, ElMessage, ElMessageBox} from 'element-plus'
import { useComposeStore } from '@/stores/compose'
import api, { basePythonURL2 } from '@/api'
import GlobalParams from '@/components/GlobalParams.vue'
import ProcessingProgress from '@/components/ProcessingProgress.vue'
import CombinationEditDialog from '@/components/CombinationEditDialog.vue'
import PresetManagerDialog from '@/components/PresetManagerDialog.vue'
import {Collection, Delete, Setting, View} from "@element-plus/icons-vue";

const router = useRouter()
const composeStore = useComposeStore()

// 响应式数据
const processingTasks = ref([])
const editDialogVisible = ref(false)
const editingCombination = ref(null)
const showPresetSelector = ref(false)
const recentPresets = ref([])
const paramsExpanded = ref(true) // 参数面板展开状态

// 数字人选择相关
const humanList = ref([])
const humanLoading = ref(false)
const humanPage = ref(1)
const humanPageSize = ref(12) // 增加每页显示数量
const humanTotal = ref(0)
const humanSearchKeyword = ref('')
const humanSortBy = ref('time_desc')
let humanSearchTimer = null

// 背景选择相关
const backgroundList = ref([])
const bgLoading = ref(false)
const bgPage = ref(1)
const bgPageSize = ref(12) // 增加每页显示数量
const bgTotal = ref(0)
const bgSearchKeyword = ref('')
const bgSortBy = ref('time_desc')
const bgFilterType = ref('all')
let bgSearchTimer = null

// 从store获取数据
const selectedHumans = computed(() => composeStore.selectedHumans)
const selectedBackgrounds = computed(() => composeStore.selectedBackgrounds)
const globalParams = computed({
  get: () => composeStore.globalParams,
  set: (value) => composeStore.updateGlobalParams(value)
})
const combinations = computed(() => composeStore.combinations)

// 计算属性
const canGenerateCombinations = computed(() => {
  return selectedHumans.value.length > 0 && selectedBackgrounds.value.length > 0
})

// 方法
const isHumanSelected = (fileId) => {
  return selectedHumans.value.some(h => h.file_id === fileId)
}

const isBackgroundSelected = (fileId) => {
  return selectedBackgrounds.value.some(b => b.file_id === fileId)
}

const toggleHumanSelection = (human) => {
  if (isHumanSelected(human.file_id)) {
    composeStore.removeHuman(human.file_id)
  } else {
    composeStore.addHuman(human)
  }
}

const toggleBackgroundSelection = (background) => {
  if (isBackgroundSelected(background.file_id)) {
    composeStore.removeBackground(background.file_id)
  } else {
    composeStore.addBackground(background)
  }
}

const handleGenerateCombinations = () => {
  composeStore.generateCombinations()
  ElMessage.success(`已生成 ${combinations.value.length} 个组合`)
}

const loadHumans = async () => {
  humanLoading.value = true
  try {
    const params = {
      page: humanPage.value,
      pageSize: humanPageSize.value,
      search: humanSearchKeyword.value,
      sortBy: humanSortBy.value
    }

    const result = await api.getLibraryFiles('human', params.page, params.pageSize, params)
    humanList.value = result.items || []
    humanTotal.value = result.total || 0
  } catch (error) {
    console.error('加载数字人失败:', error)
    ElMessage.error('加载数字人失败')
  } finally {
    humanLoading.value = false
  }
}

const loadBackgrounds = async () => {
  bgLoading.value = true
  try {
    const params = {
      page: bgPage.value,
      pageSize: bgPageSize.value,
      search: bgSearchKeyword.value,
      sortBy: bgSortBy.value,
      filterType: bgFilterType.value
    }

    const result = await api.getLibraryFiles('background', params.page, params.pageSize, params)
    backgroundList.value = result.items || []
    bgTotal.value = result.total || 0
  } catch (error) {
    console.error('加载背景失败:', error)
    ElMessage.error('加载背景失败')
  } finally {
    bgLoading.value = false
  }
}

const loadRecentPresets = async () => {
  try {
    const result = await api.getPresets()
    if (result.success) {
      // 取最近的5个预设
      recentPresets.value = result.presets.slice(0, 5)
    }
  } catch (error) {
    console.error('加载预设失败:', error)
  }
}

const goToHumanLibrary = () => {
  router.push('/human-library')
}

const goToMaterialLibrary = () => {
  router.push('/material-library')
}

const searchHumans = () => {
  clearTimeout(humanSearchTimer)
  humanSearchTimer = setTimeout(() => {
    humanPage.value = 1
    loadHumans()
  }, 300)
}

const searchBackgrounds = () => {
  clearTimeout(bgSearchTimer)
  bgSearchTimer = setTimeout(() => {
    bgPage.value = 1
    loadBackgrounds()
  }, 300)
}

const getFileType = (filename) => {
  const ext = filename.split('.').pop().toLowerCase()
  if (['jpg', 'jpeg', 'png'].includes(ext)) return 'image'
  if (ext === 'gif') return 'gif'
  if (['mov', 'mp4'].includes(ext)) return 'video'
  return 'other'
}

const getFileTypeTagType = (filename) => {
  const type = getFileType(filename)
  const typeMap = {
    'image': '',
    'gif': 'warning',
    'video': 'success',
    'other': 'info'
  }
  return typeMap[type] || 'info'
}

const applyGlobalParams = () => {
  composeStore.applyGlobalParamsToAll()
  ElMessage.success('已应用全局参数到所有组合')
}

const applyGlobalPreset = async (preset) => {
  try {
    // 应用预设到全局参数
    const { name, description, id, created_time, updated_time, ...presetParams } = preset

    // 使用nextTick确保更新是异步的
    await nextTick()
    composeStore.updateGlobalParams(presetParams)

    ElMessage.success(`已应用预设: ${preset.name}`)
  } catch (error) {
    console.error('应用预设失败:', error)
    ElMessage.error('应用预设失败')
  }
}

const clearAllCombinations = () => {
  ElMessageBox.confirm('确定要清空所有组合吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    composeStore.combinations.splice(0)
    composeStore.clearSelections()
    ElMessage.success('已清空所有组合')
  }).catch(() => {})
}

const editCombination = (combination) => {
  editingCombination.value = combination
  editDialogVisible.value = true
}

const updateCombinationParams = (updateData) => {
  if (editingCombination.value && updateData) {
    // 更新组合参数
    if (updateData.params) {
      Object.assign(editingCombination.value.params, updateData.params)
      editingCombination.value.isCustomParams = true
    }

    // 更新输出名称
    if (updateData.output_name) {
      editingCombination.value.output_name = updateData.output_name
    }

    ElMessage.success('组合参数已更新')
  }
}

const updateCombinationName = (combination) => {
  // 名称已经通过v-model更新
}

const removeCombination = (combination) => {
  composeStore.removeCombination(combination.id)
}

const processSingle = async (combination) => {
  try {
    const data = {
      human_file_id: combination.human.file_id,
      background_file_id: combination.background.file_id,
      ...combination.params,
      output_name: combination.output_name
    }

    const result = await api.processVideo(data)
    if (result.success) {
      processingTasks.value.push({
        task_id: result.task_id,
        combination
      })
      // ElMessage.success('任务已提交')
    }
  } catch (error) {
    ElMessage.error('提交任务失败')
  }
}

const batchProcess = async () => {
  try {
    await ElMessageBox.confirm(
        `确定要批量处理所有 ${combinations.value.length} 个组合吗？`,
        '批量处理确认',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
    )

    for (const combination of combinations.value) {
      await processSingle(combination)
    }

    ElMessage.success(`已提交 ${combinations.value.length} 个处理任务`)
  } catch (error) {
    // 用户取消
  }
}

const handleProcessComplete = (taskId) => {
  const index = processingTasks.value.findIndex(t => t.task_id === taskId)
  if (index > -1) {
    processingTasks.value.splice(index, 1)
  }

  if (processingTasks.value.length === 0) {
    ElMessageBox.confirm(
        '所有任务处理完成，可在历史记录查看',
        'Success',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'success',
        }
    ).finally(()=>{
      loadHumans() // 刷新文件列表
      loadBackgrounds()
    })
  }
}

const formatFileSize = (bytes) => {
  if (bytes === 0) return '0 Bytes'
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 生命周期
onMounted(() => {
  loadHumans()
  loadBackgrounds()
  loadRecentPresets()
})
</script>

<style lang="scss" scoped>
.compose-page {
  max-width: 1600px; // 增加最大宽度
  margin: 0 auto;
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;

  span {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 18px;
    font-weight: 600;
  }

  .header-actions {
    display: flex;
    gap: 10px;
  }
}

.selection-card {
  height: 700px; // 增加高度

  ::v-deep(.el-card__body) {
    height: calc(100% - 60px);
    overflow-y: auto;
    display: flex;
    flex-direction: column;
  }

  .selected-count {
    font-size: 14px;
    color: #67c23a;
    font-weight: normal;
  }
}

.selection-controls {
  display: flex;
  gap: 12px;
  margin-bottom: 16px;
}

.selection-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); // 增加最小宽度
  gap: 15px; // 增加间距
  flex: 1;
  align-content: start;
}

.selection-pagination {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid #ebeef5;
  display: flex;
  justify-content: center;
}

.selection-item {
  position: relative;
  cursor: pointer;
  border: 2px solid transparent;
  border-radius: 8px;
  overflow: hidden;
  transition: all 0.3s ease;
  background: white;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);

  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  }

  &.selected {
    border-color: #409eff;
    box-shadow: 0 0 0 3px rgba(64, 158, 255, 0.2);
  }
}

.item-preview {
  width: 100%;
  height: 220px; // 增加预览图高度
  display: block;
}

.image-error {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  background: #f5f7fa;
  color: #c0c4cc;
  font-size: 32px;
}

.item-info {
  padding: 10px; // 增加内边距
  background: white;

  .item-name {
    display: block;
    font-size: 13px; // 稍微增加字体大小
    margin-bottom: 6px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: #303133;
    line-height: 1.4;
  }

  .el-tag {
    font-size: 11px;
  }
}

.selected-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 26px;
  height: 26px;
  background: #409eff;
  color: white;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
}

.generate-combinations-wrapper {
  text-align: center;
  margin: 40px 0; // 增加上下边距

  .el-button {
    padding: 16px 50px; // 增加按钮内边距
    font-size: 18px;
  }
}

.params-card {
  margin-top: 30px;

  .quick-presets {
    margin-bottom: 20px;
    padding: 18px; // 增加内边距
    background: #f8f9fa;
    border-radius: 8px;

    .preset-label {
      font-size: 15px; // 增加字体大小
      color: #606266;
      margin-bottom: 10px;
    }

    .preset-buttons {
      display: flex;
      flex-wrap: wrap;
      gap: 10px; // 增加间距
    }
  }

  // 折叠过渡动画
  ::v-deep(.el-collapse-transition) {
    transition: all 0.3s ease;
  }

  // 展开/折叠按钮样式
  .header-actions {
    .el-button {
      transition: all 0.3s ease;

      &:hover {
        transform: translateY(-1px);
      }
    }
  }
}

.combinations-card {
  margin-top: 30px;

  .combination-preview {
    display: flex;
    align-items: center;
    gap: 6px; // 增加间距
    color: #409eff;
    cursor: pointer;
    font-size: 14px; // 增加字体大小

    &:hover {
      text-decoration: underline;
    }
  }

  ::v-deep(.el-table) {
    .el-table__cell {
      padding: 12px 0; // 增加表格行高
    }
  }
}

// 页面卡片的通用样式优化
.page-card {
  border-radius: 12px; // 增加圆角
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); // 增强阴影
  margin-bottom: 24px; // 增加底边距

  ::v-deep(.el-card__header) {
    padding: 20px 24px; // 增加头部内边距
    border-bottom: 1px solid #f0f2f5;
  }

  ::v-deep(.el-card__body) {
    padding: 24px; // 增加内容区内边距
  }
}

// 响应式设计优化
@media (max-width: 1200px) {
  .compose-page {
    max-width: 100%;
    padding: 16px;
  }

  .selection-grid {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  }
}

::v-deep(.el-dialog){
  margin: 1em auto 50px;
}
</style>